#include "WaterEmitter.h"
#include "AppSettings.h"

using namespace NxOgre::Enums;

WaterEmitter::WaterEmitter(Ogre::String name, Critter::RenderSystem*  mRenderSystem, Ogre::SceneManager *mSceneMgr)
{
	this->mRenderSystem = mRenderSystem;
	this->name = name;

	//setting default fluid params
	mMaxParticles = 2500; //2500
    mKernelRadiusMultiplier = 2.0f;
    mRestParticlesPerMetre = 15.0f;
    mMotionLimitMultiplier = 3.0f;
    mPacketSizeMultiplier = 8;
    mCollisionDistanceMultiplier = 0.1f;
    mStiffness = 10.0f;
    mViscosity = 10.0f;
    mRestDensity = 1000.0f;
	mSimulationMethod = NxOgre::Enums::FluidSimulationMethod_SPH;
  
	//setting default emitter params
    mPoseX = 0;
	mPoseY = 3;
	mPoseZ = 0;
	mShape = NxOgre::Enums::FluidEmitterShape_Ellipse;
	mParticleLifetime = 50.0;
	mRate = 50; //50
	mFluidSpeed = 0.1;
	mType = FluidEmitterType_FlowRate;
	mReplusionCoefficient = 0.8f;
	mDimensionX = 1.2f;
	mDimensionY = 1.2f;
	mParticleSize = 4.0f;

	emitterEntity = mSceneMgr->createEntity("Emitter.mesh");
	emitterSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	emitterSceneNode->attachObject(emitterEntity);
	emitterSceneNode->setScale(0.01,0.01,0.01);
	emitterEntity->setCastShadows(false);

	extern AppSettings settings;

	if(settings.applicationSettings.bSandBoxMode && (!settings.applicationSettings.bLogBenchmark))
	{
		emitterSceneNode->setVisible(true);
	}
	else
	{
		emitterSceneNode->setVisible(false);
	}
}

//--------------------------------------------------------------------------------------------

WaterEmitter::~WaterEmitter(void)
{
	emitterSceneNode->detachAllObjects();
	setStatic();
	delete ((Critter::ParticleRenderable*)mFluid->getRenderable());
}

//--------------------------------------------------------------------------------------------

Ogre::String WaterEmitter::getName(void)
{
	return name;
}

//--------------------------------------------------------------------------------------------

void WaterEmitter::setName(Ogre::String name)
{
	this->name = name;
}
//--------------------------------------------------------------------------------------------

void WaterEmitter::setStatic(void)
{
	mEmitter->setFlag(FluidEmitterFlags_Enabled,false);
	mFluid->setFlag(FluidFlags_Enabled,false);
	mFluid->removeAllParticles();
}

//--------------------------------------------------------------------------------------------

void WaterEmitter::makeWaterEmitter(void)
{
	  extern AppSettings settings;

	  NxOgre::FluidDescription desc;
	  desc.mMaxParticles = mMaxParticles;
	  desc.mKernelRadiusMultiplier = mKernelRadiusMultiplier;
	  desc.mRestParticlesPerMetre = mRestParticlesPerMetre;
	  desc.mMotionLimitMultiplier = mMotionLimitMultiplier;
	  desc.mPacketSizeMultiplier = mPacketSizeMultiplier;
	  desc.mCollisionDistanceMultiplier = mCollisionDistanceMultiplier;
	  desc.mStiffness = mStiffness;
	  desc.mViscosity = mViscosity;
	  desc.mRestDensity = mRestDensity;
	  desc.mSimulationMethod = mSimulationMethod;
	  if(settings.applicationSettings.bUseHardwarePhysX)
	  {
			 desc.mFlags |= FluidFlags_Hardware;
	  }
	  desc.mFlags |= FluidFlags_Hardware;
      //BaseWhiteNoLighting Examples/Water
	  mFluid = mRenderSystem->createFluid(desc, "Examples/Water", Critter::Enums::FluidType_OgreParticle);
	  ((Critter::ParticleRenderable*)mFluid->getRenderable())->getParticleSystem()->setDefaultDimensions(mParticleSize,mParticleSize);

	  NxOgre::FluidEmitterDescription edesc;
	  edesc.mPose.set(mPoseX, mPoseY, mPoseZ);
	  edesc.mShape = mShape;
	  edesc.mParticleLifetime = mParticleLifetime;
	  edesc.mRate = mRate;
	  edesc.mFluidSpeed = mFluidSpeed;
	  edesc.mType = mType;
	  edesc.mReplusionCoefficient = mReplusionCoefficient;
	  edesc.mDimensionX = mDimensionX;
	  edesc.mDimensionY = mDimensionY;
  
	  mEmitter = mFluid->createEmitter(edesc);

	printf("\n%s","--------------------------------------------------");
	printf("\n%s","Water emitter created...");
	printf("\n%s","--------------------------------------------------");
}

//--------------------------------------------------------------------------------------------

NxOgre::FluidEmitter* WaterEmitter::getEmitter(void)
{
	return mEmitter;
}

//--------------------------------------------------------------------------------------------

NxOgre::Fluid* WaterEmitter::getFluid(void)
{
	return mFluid;
}

//--------------------------------------------------------------------------------------------

Critter::RenderSystem*  WaterEmitter::getRenderSystem(void)
{
	return mRenderSystem;
}

//---------------------------------------------------------------------------------------------

NxOgre::Vec3 WaterEmitter::getPosition(void)
{
	return NxOgre::Vec3(this->mPoseX, this->mPoseY, this->mPoseZ);
}

//---------------------------------------------------------------------------------------------

void WaterEmitter::setPosition(NxOgre::Vec3 position)
{
	this->mPoseX = position.x;
	this->mPoseY = position.y;
	this->mPoseZ = position.z;
	
	emitterSceneNode->setPosition(position.x,position.y,position.z);
}

//---------------------------------------------------------------------------------------------
